package se.statifyme.server.services;

import java.util.Collection;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

import se.statifyme.server.declaration.ItemDeclaration;
import se.statifyme.server.declaration.ItemDeclarationGenerator;
import se.statifyme.server.entities.Record;
import se.statifyme.shared.RecordServiceConstants;

public abstract class RecordServiceImpl<E extends Record> extends OwnedItemServiceImpl<E> implements RecordService<E> {
	
	public static final String SLASH = "/";
	private E example;
	
	@GET
	@Path(RecordServiceConstants.PATH_RECORD_EXAMPLE + SLASH)
	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
	@Override
	public final E getExample(@Context HttpServletRequest request) {
		return getExample();
	}

	@GET
	@Path(RecordServiceConstants.PATH_RECORD_DECLARATION + SLASH)
	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
	@Override
	public ItemDeclaration getRecordDeclaration(@Context HttpServletRequest request) {
		return ItemDeclarationGenerator.INSTANCE.generate(getExample().getClass());
	}

	@GET
	@Path(RecordServiceConstants.PATH_RECORD + "/{id}")
	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
	@Override
	public E get(@Context HttpServletRequest request, @PathParam("id") String id) {
		return super.get(request, id);
	}

	@GET
	@Path(RecordServiceConstants.PATH_RECORD + SLASH)
	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
	@Override
	public Collection<E> getAll(@Context HttpServletRequest request) {
		return super.getAll(request);
	}

	@POST
	@Path(RecordServiceConstants.PATH_RECORD + SLASH)
	@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
	@Override
	public void save(@Context HttpServletRequest request, E item) {
		super.save(request, item);
	}

	@DELETE
	@Path(RecordServiceConstants.PATH_RECORD + "/{id}")
	@Override
	public void delete(@Context HttpServletRequest request, @PathParam("id") String id) {
		super.delete(request, id);
	}
	
	protected abstract E createExampleEntity();
	
	protected final E getExample() {
		if (example == null) {
			log("Creating entity example.");
			example = createExampleEntity();
			log("Example created: " + example);
			if (example == null) {
				throw new IllegalStateException(getClass().getSimpleName() + " Created example entity was null.");
			}
		}
		return example;
	}
	
	protected void log(Object o) {
		Logger.getLogger("StatifyMe").fine(getClass().getSimpleName() + ": " + o);
	}
	
}
